home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
011
/
nosnow.arc
/
NOSNOW.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1985-11-09
|
10KB
|
218 lines
program nosnow;
{======================================================================}
{ }
{ 2 procedures to write 1 byte to the display; avoid "snow" }
{ 1 procedure to build an entire screen, 500 bytes at a time; avoid }
{ "snow". }
{ }
{ NOTE: These procedures are released to the public domain on the }
{ condition that nobody tells on me. There are a lot of skiers here }
{ in Salt Lake City who would get very mad at somebody who was trying }
{ to eliminate snow! }
{ }
{======================================================================}
{ By Michael Quinlan 7/1/85 }
{======================================================================}
{ }
{ NoSnow1 is not as fast as NoSnow2, but it has these advantages: }
{ }
{ 1. Should work on almost any PC compatible, }
{ 2. Should work with almost any display adaptor and monitor. }
{ 3. Absolutely no "snow". }
{ }
{ It works by calling the BIOS to position the cursor, then calling }
{ the BIOS again to write the character. }
{ }
{======================================================================}
procedure NoSnow1(r, c : integer; ch : char; a : byte);
{ r = row (1..25)
c = column (1..80)
ch = character to write
a = attribute of character }
begin
Inline(
$8a/$76/<r/ { mov dh,r[bp] ;get row }
$fe/$ce/ { dec dh ;convert row to [0..24] }
$8a/$56/<c/ { mov dl,c[bp] ;get col }
$fe/$ca/ { dec dl ;convert col to [0..79] }
$b7/$00/ { mov bh,0 ;page }
$b4/$02/ { mov ah,2 ;set cursor position }
$cd/$10/ { int $10 ;have BIOS do the dirty work }
$b7/$00/ { mov bh,0 ;page }
$b9/>1/ { mov cx,1 ;number of copies }
$8a/$46/<ch/ { mov al,ch[bp] ;character }
$8a/$5e/<a/ { mov bl,a[bp] ;attribute }
$b4/$09/ { mov ah,9 ;write attr/char }
$cd/$10) { int $10 ;have BIOS do the dirty work }
end;
{======================================================================}
{ }
{ NoSnow2 writes a single character as fast as possible to the }
{ display buffer. It seems that there is still some "snow" on the }
{ left edge of the screen (it usually isn't very noticable). The code }
{ only works with the color graphics adaptor in 25x80 text mode. It }
{ would be simple (but useless) to change the code to work with other }
{ adaptors. }
{ }
{ NoSnow2 only works on an IBM PC or highly compatible. }
{ }
{======================================================================}
procedure NoSnow2(r, c : integer; ch : char; a : byte);
{ r = row (1..25)
c = column (1..80)
ch = character to write
a = attribute of character }
begin
Inline(
$8a/$46/<r/ { mov al,r[bp] ;get row }
$fe/$c8/ { dec al ;convert to [0..24] }
$bb/>80/ { mov bx,80 ;# columns per row }
$f7/$e3/ { mul bx ;calc offset into display buffer }
$03/$46/<c/ { add ax,c[bp] ;add in column }
$48/ { dec ax ;adjust for column in [0..79] }
$03/$c0/ { add ax,ax ;mult by to to get buffer offset }
$8b/$f8/ { mov di,ax ;save offset for later }
$b8/$b800/ { mov ax,$b800 ;color display base }
$1e/ { push ds ;save seg reg }
$8e/$d8/ { mov ds,ax }
$8a/$5e/<ch/ { mov bl,ch[bp] ;character }
$8a/$7e/<a/ { mov bh,a[bp] ;attribute }
$ba/$03da/ { mov dx,$3da ;color status port }
$fa/ { cli ;don't allow interrupts }
{L1:}
$ec/ { in al,dx ;wait for partial horiz. retrace }
$a8/$01/ { test al,1 }
$75/$fb/ { jnz L1 }
{L2:}
$ec/ { in al,dx ;wait for horiz retrace }
$a8/$01/ { test al,1 }
$74/$fb/ { jz L2 }
{ horizontal retrace in progress. we must move very quickly here... }
$89/$1d/ { mov [di],bx ;put char, attr in AX }
$fb/ { sti ;now allow interrupts }
$1f); { pop ds ;restore seg reg }
end;
{======================================================================}
{ }
{ Procedure ColorFlash writes an entire screen to the display buffer. }
{ It waits for the vertical retrace, then moves 500 bytes (250 }
{ characters and attributes) at a time. It is amazingly fast and is }
{ completely free of flicker and snow. }
{ }
{ ColorFlash only works on an IBM PC or highly compatible, with the }
{ color graphics adaptor. As with NoSnow2, it would be easy to change }
{ the code to work with other adaptors (but why? other adaptors don't }
{ have the hardware bug that causes "snow" in the first place...). }
{ }
{ This code may leave interrupts disabled for too long. Some high }
{ speed communications applications, for example, may lose characters }
{ while we are waiting for the vertical retrace. }
{ }
{======================================================================}
type FlashBufferType = array [1..25] of
array [1..80] of
record
c : char;
a : byte
end;
procedure ColorFlash(var d : FlashBufferType);
begin
inline(
$1E/ { PUSH DS ;save reg used }
$B8/$B800/ { MOV AX,0B800h ;dest. segment }
$8E/$C0/ { MOV ES,AX }
$BF/$00/$00/ { MOV DI,0 ;dest. offset }
$8B/$76/$04/ { MOV SI,4[BP] ;source offset }
$8E/$5e/$06/ { MOV DS,6[BP] ;source segment }
$BA/$03DA/ { MOV DX,03DAh ;status register }
$FC/ { CLD ;go forwards }
$BB/$08/$00/ { MOV BX,8 ;8*250 = 2000 words }
{LOOP:}
$B9/$FA/$00/ { MOV CX,250 ;250 words/500 bytes }
$FA/ { CLI ;don't allow interrupts }
{WAIT1: ;wait for any partially complete vertical retrace to finish }
$EC/ { IN AL,DX }
$A8/$08/ { TEST AL,08h }
$75/$FB/ { JNZ WAIT1 }
{WAIT2: ;wait for the next vertical retrace to begin }
$EC/ { IN AL,DX }
$A8/$08/ { TEST AL,08h }
$74/$FB/ { JZ WAIT2 }
{ vertical retrace in progress; copy part of the buffer }
$F3/$A5/ { REP MOVSW ;move 250 word chunk }
$FB/ { STI ;allow interrupts }
$4B/ { DEC BX ;more left to move? }
$75/$EC/ { JNZ LOOP ;yes -- loop back }
$1F) { POP DS ;no -- done }
end;
{======================================================================}
{ }
{ simple code to show off the above routines. }
{ }
{======================================================================}
var i, j : integer;
b : FlashBufferType;
begin
{ prepare for "ColorFlash" routine }
for i := 1 to 25 do
for j := 1 to 80 do
with b[i, j] do begin
a := $1e;
c := '?'
end;
ClrScr;
GotoXY(1,25);
write('Ready to Begin, Press Enter...');
ReadLn;
ClrScr;
for i := 1 to 25 do
for j := 1 to 79 do begin
GotoXY(j, i);
write('z')
end;
GotoXY(1,25);
Write('Turbo Pascal Write Done, Press Enter...');
ReadLn;
ClrScr;
for i := 1 to 25 do
for j := 1 to 80 do
NoSnow1(i, j, 'x', $1e);
GotoXY(1,25);
write('NoSnow1 Done, Press Enter...');
ReadLn;
ClrScr;
for i := 1 to 25 do
for j := 1 to 80 do
NoSnow2(i, j, 'a', $1e);
GotoXY(1,25);
write('NoSnow2 Done, Press Enter...');
ReadLn;
{ ClrScr;}
ColorFlash(b);
GoToXY(1,25);
write('ColorFlash Done, Press Enter...');
ReadLn
end.